<script setup lang='ts'>
import { ref,reactive, onMounted, onBeforeMount, onBeforeUnmount } from 'vue'

// 引入three.js
import * as THREE from 'three'
import { ArcballControls } from 'three/examples/jsm/controls/ArcballControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import localforage from 'localforage'
import { useRoute } from 'vue-router'
import Axios from 'axios'
import { FetchLatestWindValue } from '@/api/home'
import {
  GetLatestCMSClazz,
  getBarWheelMachine
} from '@/api/publicApi'

defineProps({
  type: {
    type: Number,
    default: 1
  }
})

// 定义变量
// 展示风速信息
const showElement = ref(false)
// 展示信息
const isShow = ref(false)
// 选择的视角
const viewNum = ref(0)
// 
const threeUrl = ref('')
// 
const fileTotal = ref('')
// 
const modelType:any = ref([])
// 定时器
const inteVal:any = ref()
// 堆取料机列表
let BarWheelMachineList:any = reactive({})
// 机器状态
const barStata = ref('')
// 
const WindSpeedValue = ref(0)
// 
const CmsClazzObj = reactive( {
  carStrokePosition: 0,
  carRotatePosition: 0,
  carPitchPosition: 0
})

const path = ref('/')
// 是否为堆料机
const isStockpile = ref(false)

// three.js场景变量
let scene
let camera
let renderer
let controls
let ProgressTatol = ref()
let Progress = ref(true)

// 模型文件
const gltfData:any = ref()

// 模型文件名称
const threeFileName = ref('')
const threeFileName1 = ref('')
const threeFileName2 = ref('')

// 定义函数
onBeforeMount(() => {
  threeUrl.value = './'
  threeFileName.value = window.Glob.HOME_3D_FILE_NAME1
  let arr = threeFileName.value.split('-')[1]
  fileTotal.value = arr.split('.')[0]
  let route = useRoute()
  path.value = route.fullPath
  isStockpile.value = (route.fullPath.split('-')[1] === 'D') ? true : false
  console.log('3D模型----->', isStockpile, route.fullPath.split('-')[0])
  try {
    if (route.fullPath !== '/') {
      modelType.value = route.fullPath.split('-')
      if (modelType.value[1] === 'DQ') {
        showElement.value = true
        threeFileName1.value = window.Glob.HOME_3D_FILE_NAME4 //堆取料机点位模型
        threeFileName2.value = window.Glob.HOME_3D_FILE_NAME5
      } else if (modelType.value[1] === 'D') {
        showElement.value = true
        threeFileName.value = window.Glob.HOME_3D_FILE_NAME3
        // this.three_file_name1 = window.Glob.HOME_3D_FILE_NAME5; //堆料机点位模型
        // threeFileName1.value = window.Glob.HOME_3D_FILE_NAME5
      } else if (modelType.value[1] === 'Q') {
        showElement.value = true
        // this.three_file_name1 = window.Glob.HOME_3D_FILE_NAME4; //取料机点位模型
        // threeFileName1.value = window.Glob.HOME_3D_FILE_NAME4
        threeFileName.value = window.Glob.HOME_3D_FILE_NAME2
      } else {
        showElement.value = false
        threeFileName1.value = window.Glob.HOME_3D_FILE_NAME4
      }
    } else {
      showElement.value = false
    }
  } catch (error) {
    console.log('error', error)
  }
  
  // if(route.fullPath !== '/homePage') {
  //   isShow.value = true
  // }
  // console.log('useRoute------->',route.fullPath)
  // showElement.value = true
  // if(route.fullPath === '/homePage') {
  //   threeFileName.value = 'untitled123-45440394.gltf'
  // } else {
  //   threeFileName.value = 'untitled123-12640843.gltf'
  //   console.log('现在的视角---->aaaa', route.fullPath)
  // }
})

onMounted(async () => {
  init()
  // 判断本地是否有模型缓存
  gltfData.value = await localforage.getItem(threeFileName.value)
  if (gltfData.value instanceof Blob) {
    load()
    // console.log('加载缓存');
  } else {
    getGltf()
    // console.log('没有缓存');
  }
  getMachineData()
  // inteVal.value = setInterval(() => {
  //   getMachineData()
  // }, 10000)
})

// 获取机器数据
const getMachineData = () => {
  // 获取堆取料机工作状态及堆取料量信息
  getBarWheelMachine({ Code: localStorage.BarWheelMachineCode }).then(res => {
    res.result.items.forEach(item => {
      if (item.code === localStorage.BarWheelMachineCode) {
        BarWheelMachineList = item 
        barStata.value =
          BarWheelMachineList.machineStatus === 0
            ? '停止'
            : BarWheelMachineList.machineStatus === 1
              ? '堆料'
              : BarWheelMachineList.machineStatus === 2
                ? '取料'
                : '异常'
      }
    })
    console.log('3D模型状态信息--------->', barStata, res)
  })

  // 获取风速风向
  FetchLatestWindValue({ BarWheelMachineCode: localStorage.BarWheelMachineCode, Sorting: 'id asc' }).then(res => {
    WindSpeedValue.value = res.result.hyperWindVelcity
    console.log(WindSpeedValue)
    console.log('3D模型风速信息--------->', WindSpeedValue, res)
  }).catch(erroe => {
    console.log('3D模型风速信息错误--------->', CmsClazzObj, erroe)
  })

  // 模型的位置信息
  GetLatestCMSClazz({
    BarWheelMachineCode: localStorage.BarWheelMachineCode
      ? localStorage.BarWheelMachineCode
      : null
  }).then(res => {
    CmsClazzObj.carPitchPosition = res.result.carPitchPosition
    CmsClazzObj.carRotatePosition = res.result.carRotatePosition
    CmsClazzObj.carStrokePosition = res.result.carStrokePosition
    console.log('3D模型位置信息--------->', CmsClazzObj, res)
  }).catch(erroe => {
    console.log('3D模型位置信息错误--------->', CmsClazzObj, erroe)
  })
  
}

// 初始化3D模型
const init = () => {
  let targetCanvas = document.getElementById('canvas') as HTMLElement

  let documentWidth = (document.querySelector('#canvas') as HTMLElement).offsetWidth
  let documentHeight = (document.getElementById('canvas') as HTMLElement).offsetHeight

  // 创建场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0xB2CCE5)
  // 创建相机 
  camera = new THREE.PerspectiveCamera(75, documentWidth / documentHeight, 1, 100000)
  // camera.position.z = 950

  // 判断除堆取料机外的模型中心点太高  位置下降显示
  console.log('堆取料机3D模型aaaa----->', modelType.value[1], path.value)
  if (path.value === '/homePage') {
    camera.position.z = 950
  } else if (modelType.value[1] === 'Q') {
    console.log('取料机3D模型----->' )
    camera.position.set(-0.11, 30.75, -40)
    // this.camera.lookAt(0,15,0)//每次移动相机位置的时候  需要重置相机看向的目标
  } else if (modelType.value[1] === 'D') {
    console.log('堆料机3D模型----->')
    camera.position.set(0, 0, -50.24)
    // this.camera.lookAt(0,100,0)
  } else if (modelType.value[1] === 'DQ') {
    console.log('堆取料机3D模型----->')
    camera.position.z = 600
    //  this.camera.position.set(0,0,1) 
  }
  
  // 修改相机三维轴承显示方向
  camera.up = new THREE.Vector3(0, 1, 0)

  // 平行光
  const directionalLight = new THREE.DirectionalLight(0xffffffff, 6)
  const directionalLight2 = new THREE.DirectionalLight(0xffffffff, 6)
  directionalLight.position.x = 1
  directionalLight.position.y = 1
  directionalLight.position.z = 1
  directionalLight2.position.x = -1
  directionalLight2.position.y = -1
  directionalLight2.position.z = -1

  scene.add(directionalLight)
  scene.add(directionalLight2)

  // 创建渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.outputEncoding = THREE.sRGBEncoding
  renderer.setSize(documentWidth, documentHeight)
  renderer.domElement.style = 'width:100%;height:100%;'
  targetCanvas.appendChild(renderer.domElement)
  
  // 添加控制器
  controls = new ArcballControls(camera, renderer.domElement, scene)
  
  // 控制辅助坐标显示
  controls.setGizmosVisible(false)
  
  controls.addEventListener('change', () => {
    // 获取右键拖动后的lookat定位
    var target = new THREE.Vector3()
    camera.getWorldDirection(target)
    target.add(camera.position)
    renderer.render(scene, camera) //执行渲染操作
  })
  renderer.render(scene,camera)
}

// 加载模型
const load = async() => {
  //需要显示加载进度文字
  const res = await localforage.getItem(threeFileName.value)
  
  if (res instanceof Blob) {
    const URL = window.URL || window.webkitURL
    const gltfURL = URL.createObjectURL(res)
    const loader = new GLTFLoader()
    loader.load(gltfURL, (gltf:any) => {
      camera.lookAt(0, 10, 0)
      scene.add(gltf.scene)
      scene.updateMatrixWorld(true)
      renderer.render(scene, camera)
    },
    xhr => {
      var _onProgress
      if ((gltfData.value instanceof Blob)) {
        _onProgress = Math.floor(xhr.loaded / xhr.total * 100)
        
        ProgressTatol.value = _onProgress
      }
      
      if (_onProgress === 100) {
        setTimeout(() => { Progress.value = false }, 700)
      }
    })
    // 加载点位模型
    console.log('运行到此处load---->', './' + threeFileName1.value )
    const loader1 = new GLTFLoader()
    loader1.load('./' + threeFileName1.value, gltf => {
      camera.lookAt(0, 10, 0)
      scene.add(gltf.scene)
      scene.updateMatrixWorld(true)
      renderer.render(scene, camera)
    })

  }
}

// 获取模型
const getGltf = () => {
  console.log('运行到此处---->')
  Axios({
    url: './' + threeFileName.value,
    method: 'get',
    responseType: 'blob',
    onDownloadProgress: function (progressEvent) {
      console.log('加载量-------->', progressEvent)
      
      // 对原生进度事件的处理
      let num = progressEvent.loaded / (progressEvent.total as number) * 100 // 计算进度        
      ProgressTatol.value = num.toFixed(1)

      if (ProgressTatol.value === 100) {
        setTimeout(() => { Progress.value = false }, 1500)
      }
      // this.$set(this.ProgressTatol)
      console.log('已加载' + ProgressTatol.value + '%')
    }
  }).then(res => {
    localforage.setItem(threeFileName.value, res.data).then(() => {
      load()
    })
  })
}

// 选择视角
const selectView = (num:number) => {
  console.log('现在的视角---->',num)
  viewNum.value = num
  switch(num) {
  case 0:
    originalPerspective()
    break
  case 1:
    bucketWheelPerspective()
    break
  case 2:
    counterweightPerspective()
    break
  case 3:
    platformLeftPerspective()
    break
  case 4:
    platformRightPerspective()
    break
  }
}
// 原始视角
const originalPerspective = () => {
  // e :根据点击的按钮获取焦点  
  controls.reset()
  camera.lookAt(0, 10, 0)
  renderer.render(scene, camera)

}
// 轮斗视角
const bucketWheelPerspective = () => {
  controls.reset()
  if (path.value === '/homePage') {
    camera.position.set(-586, 300, -45)
    camera.lookAt(-586, 0, -45)
  } else if(modelType.value[1] === 'Q') {
    camera.position.set(30, 30, -1)
    camera.lookAt(30, 0, 0)
  }  else {
    console.log('选择轮斗视角---->', path.value)
    camera.position.set(-602, 178, -77)
    camera.lookAt(-602, 177, -77)
  }
  scene.updateMatrixWorld(true)
  renderer.render(scene, camera)
}
//  配重视角
const counterweightPerspective = () => {
  controls.reset()
  if (path.value === '/homePage') {
    camera.position.set(0, 700, 0)
    camera.lookAt(0, 0, 0)
  } else if (modelType.value[1] === 'Q') {
    camera.position.set(-30, 50, -0.1)
    camera.lookAt(-30, 0, 0)
  } else if (modelType.value[1] === 'D') {
    camera.position.set(0, 49, -0.1)
    camera.lookAt(0, 0, 0)
  } else {
    camera.position.set(0, 505, 0)
    scene.updateMatrixWorld(true)
    renderer.render(scene, camera)
  }

  scene.updateMatrixWorld(true)
  renderer.render(scene, camera)

}
// 平台左视角
const platformLeftPerspective = () => {
  controls.reset()
  
  if (path.value === '/homePage') {
    camera.position.set(0, 20, 700)
    camera.lookAt(0, 0, 0)

  } else if (modelType.value[1] === 'Q') {
    camera.position.set(0, 23, -48)
    camera.lookAt(0, 15, 0)
  } else if (modelType.value[1] === 'D') {
    camera.position.set(2.2, 15.4, -50)
    camera.lookAt(0, 10, 0)
  } else {
    camera.position.set(0, 0, 465)
    camera.lookAt(0, 0, 0)
  }

  scene.updateMatrixWorld(true)
  renderer.render(scene, camera)
}
// 平台右视角
const platformRightPerspective = () => {
  controls.reset()

  if (path.value === '/homePage') {
    camera.position.set(0, 20, -700)
    camera.lookAt(0, 0, 0)

  } else if (modelType.value[1] === 'Q') {
    camera.position.set(0, 23, 48)
    camera.lookAt(0, 15, 0)

  } else if (modelType.value[1] === 'D') {
    camera.position.set(1.05, 15.4, 50)
    camera.lookAt(0, 10, 0)
  } else {
    camera.position.set(-0., -0, -464)
    camera.lookAt(-0, -0, -463)
  }

  scene.updateMatrixWorld(true)
  renderer.render(scene, camera)
}

onBeforeUnmount(() => {
  console.log('销毁')
  clearInterval(inteVal)
})
</script>

<template>
  <div class="model-main-box">
    <div
      id="canvas"
      ref="canvas"
    />
    <div
      class="wind-speed-box"
    >
      <div class="icon-box" />
      <div class="info-box">
        <span>风速：</span>
        <div>{{ WindSpeedValue }}&ensp;m/s</div>
      </div>
    </div>
    <div class="view-btn-box">
      <div
        :id="(viewNum === 0) ? 'activeView' : ''"
        @click="selectView(0)"
      >
        原始视角
      </div>
      <div
        v-if="!isStockpile"
        :id="(viewNum === 1) ? 'activeView' : ''"
        @click="selectView(1)"
      >
        轮斗视角
      </div>
      <div
        :id="(viewNum === 2) ? 'activeView' : ''"
        @click="selectView(2)"
      >
        配重视角
      </div>
      <div
        :id="(viewNum === 3) ? 'activeView' : ''"
        @click="selectView(3)"
      >
        平台左视角
      </div>
      <div
        :id="(viewNum === 4) ? 'activeView' : ''"
        @click="selectView(4)"
      >
        平台右视角
      </div>
    </div>
    <div
      v-if="type"
      class="status-box"
    >
      <div class="normal-box">
        <div style="background-color: rgb(34 243 76);" />&ensp;正常
      </div>
      <div class="first-level">
        <div style="background-color: #ede215;" />&ensp;一级报警
      </div>
      <div class="second-level">
        <div style="background-color: #fe0808;" />&ensp; 二级报警
      </div>
    </div>
    <div
      v-if="type"
      class="work-type"
    >
      <span>当前工作状态：{{ barStata }}</span>
    </div>
    <div
      v-if="type"
      class="weight-info"
    >
      <div>
        总堆料量：{{ BarWheelMachineList.stockWeight }}吨
      </div>
      <div>
        总取料量：{{ BarWheelMachineList.takeWeight }}吨
      </div>
    </div>
    <div
      v-if="type"
      class="psoi-info"
    >
      <div>当前行走位置：{{ CmsClazzObj.carStrokePosition.toFixed(1) }}米</div>
      <div>当前旋转角度：{{ CmsClazzObj.carRotatePosition }}°</div>
      <div>当前俯仰角度：{{ CmsClazzObj.carPitchPosition }}°</div>
    </div>
    <div
      v-if="Progress"
      id="progressBar"
    >
      正在加载模型请稍等：<span id="jindu-text">{{ ProgressTatol }}%</span>
    </div>
  </div>
</template>

<style scoped lang=scss>
.model-main-box {
  position: relative;
  width: 100%;
  height: 100%;

  .wind-speed-box {
    position: absolute;
    top: 20px;
    left: 20px;
    display: flex;
    align-items: center;

    /* border: 1px solid red; */

    .icon-box {
      width: 30px;
      height: 30px;
      background-image: url("../../assets/imgs/风速.png");
    }

    .info-box {
      margin-left: 4px;

      >span {
        color: #fff;
        font-size: 18px;
      }

      >div {
        margin-top: 4px;
        color: #0a7ac4;
        font-size: 16px;
      }
    }
  }

  .view-btn-box {
    position: absolute;
    top: 35%;
    left: 20px;
    width: 100px;
    height: 260px;

    /* border: 1px solid red; */

    >div {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 90px;
      height: 32px;
      margin-top: 10px;
      color: #5f5c5c;
      font-size: 14px;
      background-color: #fff;
      border-radius: 4px;

      &:hover {
        color: #409eff;
        background-color: #ffffffce;
        cursor: pointer;
      }
    }

    /* stylelint-disable-next-line selector-id-pattern */
    #activeView {
      color: #fff;
      background-color: #409eff;
    }
  }

  .status-box {
    position: absolute;
    top: 20px;
    left: 35%;
    display: flex;
    justify-content: space-around;
    width: 450px;
    height: 30px;

    /* border: 1px solid red; */

    >div {
      display: flex;
      align-items: center;
      height: 100%;

      /* border: 1px solid green; */

      >div {
        width: 50px;
        height: 18px;

        /* border: 1px solid yellow; */
      }
    }
  }

  .work-type {
    position: absolute;
    top: 96%;
    left: 20px;

    >span {
      font-size: 16px;
    }
  }

  .weight-info {
    position: absolute;
    top: 20px;
    left: 92%;

    >div {
      margin-top: 5px;
      font-size: 16px;
    }
  }

  .psoi-info {
    position: absolute;
    top: 90%;
    left: 88%;

    >div {
      margin-top: 5px;
      font-size: 16px;
    }
  }

  /* stylelint-disable-next-line selector-id-pattern */
  #progressBar {
    // height: 12%;
    position: absolute;
    top: 45%;
    left: 25%;
    box-sizing: border-box;
    width: 50%;

    // right:20%;
    margin: 0 auto;
    padding: 5px;
    font-size: 24px;
    text-align: center;
    background-color: rgb(255 255 255 / 50%);
  }

  /* stylelint-disable-next-line selector-id-pattern */
  #canvas {
    width: 100%;
    height: 100%;
    background-color: #7390ad;
    touch-action: none;
  }
}
</style>